package com.kevin.netty.server;

import com.kevin.netty.server.handler.HttpHandler;
import com.kevin.netty.server.handler.WebSocketHandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class ChatServer {

	private static final int PORT = 80;
	
	
	public static void main(String[] args) {
		new ChatServer();
	}
	
	/**
	 * 启动服务
	 */
	public void start(){
		// 启动boss线程
		EventLoopGroup boss = new NioEventLoopGroup();
		
		// 启动worker线程
		EventLoopGroup work = new NioEventLoopGroup();
		// 启动引擎
		ServerBootstrap b = new ServerBootstrap();
		
		// 主从模型
		b.group(boss, work)
		 .channel(NioServerSocketChannel.class)
		 .option(ChannelOption.SO_BACKLOG, 1024)
		 .childHandler(new ChannelInitializer<Channel>() {

			@Override
			protected void initChannel(Channel ch) throws Exception {
				// TODO 开始定义自己的业务
				ChannelPipeline pipeline = ch.pipeline();
				
				/******** 支持Http协议 ********/
				// 解码和编码Http请求
				pipeline.addLast(new HttpServerCodec())
						.addLast(new HttpObjectAggregator(64 * 1024))
						// 用于处理文件流的一个Handler，主要用于处理大量文件
						.addLast(new ChunkedWriteHandler())
						.addLast(new HttpHandler());
				
				/******** 支持Socket协议 ********/
				pipeline.addLast(new WebSocketServerProtocolHandler("/socket"))
				        .addLast(new WebSocketHandler());
				
			}
			 
		});
		
		// 阻塞--》等待客户端的连接
		try {
			ChannelFuture future = b.bind(this.PORT).sync();
			System.out.println("服务已经启动，正在监听端口："+this.PORT);
			future.channel().closeFuture().sync();
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}
